#include "html.h"
+#include <QChar> // for QChar
+#include <QIODevice> // for QIODevice, QIODevice::WriteOnly
#include <QString> // for QString, operator!=
+#include <QTextStream> // for QTextStream
#include <Qt> // for CaseInsensitive
#include <cstdint> // for int32_t
-#include <ctime> // for localtime, time_t, tm
+#include <ctime> // for localtime, time_t
-#include "defs.h" // for Waypoint, xfree, geocache_data, html_entitize, CSTR, pretty_deg_format, rot13, strip_nastyhtml, waypt_disp_all, utf_string, METERS_TO_FEET, gpsbabel_testmode, gs_get_cachetype, gs_get_container, mkshort_del_handle, mkshort_from_wpt, mkshort_new_handle
+#include "defs.h"
#include "formspec.h" // for FormatSpecificDataList, kFsGpx
-#include "gbfile.h" // for gbfprintf, gbfclose, gbfopen, gbfputs
#include "jeeps/gpsmath.h" // for GPS_Math_WGS84_To_UTM_EN
#include "src/core/datetime.h" // for DateTime
+#include "src/core/textstream.h" // for TextStream
#include "src/core/xmltag.h" // for xml_findfirst, xml_tag, xml_attribute, fs_xml, xml_findnext
void
HtmlFormat::wr_init(const QString& fname)
{
- file_out = gbfopen(fname, "w", MYNAME);
+ file_out = new gpsbabel::TextStream;
+ file_out->open(fname, QIODevice::WriteOnly, MYNAME);
mkshort_handle = mkshort_new_handle();
}
void
HtmlFormat::wr_deinit()
{
- gbfclose(file_out);
+ file_out->close();
+ delete file_out;
+ file_out = nullptr;
mkshort_del_handle(&mkshort_handle);
}
GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
&utme, &utmn, &utmz, &utmzc);
- gbfprintf(file_out, "\n<a name=\"%s\"><hr></a>\n", CSTR(wpt->shortname));
- gbfprintf(file_out, "<table width=\"100%%\">\n");
- gbfprintf(file_out, "<tr><td><p class=\"gpsbabelwaypoint\">%s - ",(global_opts.synthesize_shortnames) ? CSTR(mkshort_from_wpt(mkshort_handle, wpt)) : CSTR(wpt->shortname));
- gbfprintf(file_out, "%s (%d%c %6.0f %7.0f)",
- CSTR(pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", true)),
- utmz, utmzc, utme, utmn);
+ *file_out << "\n<a name=\"" << wpt->shortname << "\"><hr></a>\n";
+ *file_out << "<table width=\"100%\">\n";
+ QString sn = global_opts.synthesize_shortnames ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname;
+ *file_out << "<tr><td><p class=\"gpsbabelwaypoint\">" << sn << " - ";
+ *file_out << QStringLiteral("%1 (%2%3 %4 %5)")
+ .arg(pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", true))
+ .arg(utmz)
+ .arg(utmzc)
+ .arg(utme, 6, 'f', 0)
+ .arg(utmn, 7, 'f', 0);
if (wpt->altitude != unknown_alt) {
- gbfprintf(file_out, " alt:%d", (int)((altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude));
+ *file_out << QStringLiteral(" alt:%1")
+ .arg((int)((altunits[0]=='f') ? METERS_TO_FEET(wpt->altitude) : wpt->altitude));
}
- gbfprintf(file_out, "<br>\n");
+ *file_out << "<br>\n";
if (wpt->description != wpt->shortname) {
if (wpt->HasUrlLink()) {
- gbfputs(QStringLiteral("<a href=\"%1\">%2</a>")
- .arg(wpt->GetUrlLink().url_, html_entitize(wpt->description)),
- file_out);
+ *file_out << "<a href=\"" << wpt->GetUrlLink().url_ << "\">"
+ << html_entitize(wpt->description) << "</a>";
} else {
- gbfprintf(file_out, "%s", CSTR(wpt->description));
+ *file_out << wpt->description;
}
if (!wpt->gc_data->placer.isEmpty()) {
- gbfprintf(file_out, " by %s", CSTR(wpt->gc_data->placer));
+ *file_out << " by " << wpt->gc_data->placer;
}
}
- gbfprintf(file_out, "</p></td>\n");
+ *file_out << "</p></td>\n";
- gbfprintf(file_out, "<td align=\"right\">");
+ *file_out << "<td align=\"right\">";
if (wpt->gc_data->terr) {
- gbfprintf(file_out, "<p class=\"gpsbabelcacheinfo\">%d%s / %d%s<br>\n",
- (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10) ? "½" : "",
- (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10) ? "½" : "");
- gbfputs(QStringLiteral("%1 / %2</p>")
- .arg(gs_get_cachetype(wpt->gc_data->type),
- gs_get_container(wpt->gc_data->container)),
- file_out);
+ *file_out << QStringLiteral("<p class=\"gpsbabelcacheinfo\">%1%2 / %3%4<br>\n")
+ .arg((int)(wpt->gc_data->diff / 10))
+ .arg((wpt->gc_data->diff%10) ? "½" : "")
+ .arg((int)(wpt->gc_data->terr / 10))
+ .arg((wpt->gc_data->terr%10) ? "½" : "");
+ *file_out << gs_get_cachetype(wpt->gc_data->type) << " / "
+ << gs_get_container(wpt->gc_data->container) << "</p>";
}
- gbfprintf(file_out, "</td></tr>\n");
+ *file_out << "</td></tr>\n";
- gbfprintf(file_out, "<tr><td colspan=\"2\">");
+ *file_out << "<tr><td colspan=\"2\">";
if (!wpt->gc_data->desc_short.utfstring.isEmpty()) {
- gbfputs(QStringLiteral("<p class=\"gpsbabeldescshort\">%1</p>\n")
- .arg(strip_nastyhtml(wpt->gc_data->desc_short.utfstring)),
- file_out);
+ *file_out << "<p class=\"gpsbabeldescshort\">"
+ << strip_nastyhtml(wpt->gc_data->desc_short.utfstring) << "</p>\n";
}
if (!wpt->gc_data->desc_long.utfstring.isEmpty()) {
- gbfputs(QStringLiteral("<p class=\"gpsbabeldesclong\">%1</p>\n")
- .arg(strip_nastyhtml(wpt->gc_data->desc_long.utfstring)),
- file_out);
+ *file_out << "<p class=\"gpsbabeldesclong\">"
+ << strip_nastyhtml(wpt->gc_data->desc_long.utfstring) << "</p>\n";
}
if (!wpt->gc_data->hint.isEmpty()) {
QString hint;
} else {
hint = wpt->gc_data->hint;
}
- gbfprintf(file_out, "<p class=\"gpsbabelhint\"><strong>Hint:</strong> %s</p>\n", CSTR(hint));
+ *file_out << "<p class=\"gpsbabelhint\"><strong>Hint:</strong> "
+ << hint << "</p>\n";
} else if (!wpt->notes.isEmpty() && (wpt->description.isEmpty() || wpt->notes != wpt->description)) {
- gbfprintf(file_out, "<p class=\"gpsbabelnotes\">%s</p>\n", CSTR(wpt->notes));
+ *file_out << "<p class=\"gpsbabelnotes\">" << wpt->notes << "</p>\n";
}
if (includelogs) {
xml_tag* curlog = xml_findfirst(root, "groundspeak:log");
while (curlog) {
time_t logtime = 0;
- gbfprintf(file_out, "<p class=\"gpsbabellog\">\n");
+ *file_out << "<p class=\"gpsbabellog\">\n";
xml_tag* logpart = xml_findfirst(curlog, "groundspeak:type");
if (logpart) {
- gbfprintf(file_out, "<span class=\"gpsbabellogtype\">%s</span> by ", CSTR(logpart->cdata));
+ *file_out << "<span class=\"gpsbabellogtype\">"
+ << logpart->cdata << "</span> by ";
}
logpart = xml_findfirst(curlog, "groundspeak:finder");
if (logpart) {
- gbfputs(QStringLiteral("<span class=\"gpsbabellogfinder\">%1</span> on ")
- .arg(html_entitize(logpart->cdata)),
- file_out);
+ *file_out << "<span class=\"gpsbabellogfinder\">"
+ << html_entitize(logpart->cdata) << "</span> on ";
}
logpart = xml_findfirst(curlog, "groundspeak:date");
logtime = xml_parse_time(logpart->cdata).toTime_t();
struct tm* logtm = localtime(&logtime);
if (logtm) {
- gbfprintf(file_out,
- "<span class=\"gpsbabellogdate\">%04d-%02d-%02d</span><br>\n",
- logtm->tm_year+1900,
- logtm->tm_mon+1,
- logtm->tm_mday);
+ *file_out << QStringLiteral("<span class=\"gpsbabellogdate\">%1-%2-%3</span><br>\n")
+ .arg(logtm->tm_year+1900, 4, 10, QChar('0'))
+ .arg(logtm->tm_mon+1, 2, 10, QChar('0'))
+ .arg(logtm->tm_mday, 2, 10, QChar('0'));
}
}
if (logpart) {
double lat = xml_attribute(logpart->attributes, "lat").toDouble();
double lon = xml_attribute(logpart->attributes, "lon").toDouble();
- gbfprintf(file_out,
- "<span class=\"gpsbabellogcoords\">%s</span><br>\n",
- CSTR(pretty_deg_format(lat, lon, degformat[2], " ", true)));
+ *file_out << "<span class=\"gpsbabellogcoords\">"
+ << pretty_deg_format(lat, lon, degformat[2], " ", true) << "</span><br>\n";
}
logpart = xml_findfirst(curlog, "groundspeak:text");
s = logpart->cdata;
}
- gbfputs(html_entitize(s), file_out);
+ *file_out << html_entitize(s);
}
- gbfprintf(file_out, "</p>\n");
+ *file_out << "</p>\n";
curlog = xml_findnext(root, curlog, "groundspeak:log");
}
}
}
- gbfprintf(file_out, "</td></tr></table>\n");
+ *file_out << "</td></tr>\n";
+ *file_out << "</table>\n";
}
void
HtmlFormat::html_index(const Waypoint* wpt) const
{
- gbfputs(QStringLiteral("<a href=\"#%1\">%1 - %2</a><br>\n")
- .arg(html_entitize(wpt->shortname), html_entitize(wpt->description)),
- file_out);
+ *file_out << QStringLiteral("<a href=\"#%1\">%1 - %2</a><br>\n")
+ .arg(html_entitize(wpt->shortname), html_entitize(wpt->description));
}
void
{
setshort_length(mkshort_handle, 6);
- gbfprintf(file_out, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
- gbfprintf(file_out, "<html>\n");
- gbfprintf(file_out, "<head>\n");
- gbfprintf(file_out, " <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n");
+ *file_out << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n";
+ *file_out << "<html>\n";
+ *file_out << "<head>\n";
+ *file_out << " <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n";
// Don't write this line when running test suite. Actually, we should
// probably not write this line at all...
if (!gpsbabel_testmode()) {
- gbfprintf(file_out, " <meta name=\"Generator\" content=\"GPSBabel %s\">\n", gpsbabel_version);
+ *file_out << " <meta name=\"Generator\" content=\"GPSBabel "
+ << gpsbabel_version << "\">\n";
}
- gbfprintf(file_out, " <title>GPSBabel HTML Output</title>\n");
+ *file_out << " <title>GPSBabel HTML Output</title>\n";
if (stylesheet) {
- gbfprintf(file_out, " <link rel=\"stylesheet\" type=\"text/css\" href=\"%s\">\n", stylesheet);
+ *file_out << " <link rel=\"stylesheet\" type=\"text/css\" href=\""
+ << stylesheet << "\">\n";
} else {
- gbfprintf(file_out, " <style>\n");
- gbfprintf(file_out, " p.gpsbabelwaypoint { font-size: 120%%; font-weight: bold }\n");
- gbfprintf(file_out, " </style>\n");
+ *file_out << " <style>\n";
+ *file_out << " p.gpsbabelwaypoint { font-size: 120%; font-weight: bold }\n";
+ *file_out << " </style>\n";
}
- gbfprintf(file_out, "</head>\n");
- gbfprintf(file_out, "<body>\n");
+ *file_out << "</head>\n";
+ *file_out << "<body>\n";
- gbfprintf(file_out, "<p class=\"index\">\n");
+ *file_out << "<p class=\"index\">\n";
auto html_index_lambda = [this](const Waypoint* waypointp)->void {
html_index(waypointp);
};
waypt_disp_all(html_index_lambda);
- gbfprintf(file_out, "</p>\n");
+ *file_out << "</p>\n";
auto html_disp_lambda = [this](const Waypoint* waypointp)->void {
html_disp(waypointp);
};
waypt_disp_all(html_disp_lambda);
- gbfprintf(file_out, "</body>");
- gbfprintf(file_out, "</html>");
+ *file_out << "</body>\n";
+ *file_out << "</html>\n";
}
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <title>GPSBabel HTML Output</title>
+ <style>
+ p.gpsbabelwaypoint { font-size: 120%; font-weight: bold }
+ </style>
+</head>
+<body>
+<p class="index">
+<a href="#GCGCA8">GCGCA8 - Oozy rat in a sanitary zoo</a><br>
+</p>
+
+<a name="GCGCA8"><hr></a>
+<table width="100%">
+<tr><td><p class="gpsbabelwaypoint">GCGCA8 - N35°55.300 W86°51.700 (16S 512480 3975269)<br>
+<a href="http://www.geocaching.com/seek/cache_details.aspx?guid=cda94cd6-d657-49bd-8e7e-0031ef1b2613">Oozy rat in a sanitary zoo</a> by robertlipe</p></td>
+<td align="right"><p class="gpsbabelcacheinfo">3 / 2<br>
+Unknown Cache / Unknown</p></td></tr>
+<tr><td colspan="2"><p class="gpsbabeldescshort">The cache is not at the coordinates above. These coords will get you to the correct park and within 1/2 mile of the cache. The cache is within 35 feet of the trail. It is not handicapped accessible. It is a nice walk in the woods that is practical for all ages. There is no space in the container for trading items. You should bring a writing stick and bug spray is recommended.</p>
+<p class="gpsbabeldesclong">So if the cache isn't at the above coordinates, where is it?
+
+<ul>
+
+<li>Too bad I hid a boot
+<li>Too hot to hoot
+<li>Never odd or even
+<li>Do geese see God?
+<li>"Do nine men interpret?" "Nine men," I nod
+<li>Rats live on no evil star
+<li>Go hang a salami, I'm a lasagna hog
+</ul>
+
+Now that it's intuitively obvious to even the most casual observer where the cache is, turn on your geo-mojo and go find it.
+<br>
+<img SRC="http://www.mtgc.org/mtgc_member-banner.gif" WIDTH="500" HEIGHT="40" ALT="Member of Middle Tennessee GeoCachers Club [www.mtgc.org]" BORDER="0"></a></p></p>
+<p class="gpsbabelhint"><strong>Hint:</strong> There Is No Hint</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">littlepod</span> on <span class="gpsbabellogdate">2005-07-03</span><br>
+Enjoyed the puzzle. We seemed to be about 50ft off though. TFTC.</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2005-04-29</span><br>
+TB Drop to show he's hanging out in Nashville until we blast off for Geowoodstock in a few weeks.</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">Big Bumblebee</span> on <span class="gpsbabellogdate">2005-04-18</span><br>
+Found it a while ago. Thanks.</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2005-03-27</span><br>
+I had to renew my permit with the CDC and in doing so, I trolled out here verified that the infectious ooze is fully within specification and industry accepted tolerance. Ooze On!</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">Virtual Babe</span> on <span class="gpsbabellogdate">2004-12-27</span><br>
+This was a great cache, however on this day I considered it a FIFM cache (Fun, Invigorating, Frustrating and Maddening), especially when the cache was not replaced in the proper spot by the previous cacher! Thanks anyway!!</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2004-01-12</span><br>
+I got a complaint from the CDC about oozy rat this weekend. I went out tonight in the dark and verified that the infectious ooze is fully within specification and industry accepted tolerance. (Although I realize now I did misstate the cache container to the reporting officer when confronted. It's, uuuuh, smaller than I said.)</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2003-10-04</span><br>
+In the expectation that this cache will get some traffic in the next 48 hours, Ryan and I checked it earlier today. The Rat is Oozing just as we planned it.</p>
+<p class="gpsbabellog">
+<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2003-07-03</span><br>
+It won't earn him a smiley face, but I've confirmed that rickrich would have indeed sunk the battleship! Thanx for playing. You get a copy of the home game and some rice-a-roni...</p>
+</td></tr>
+</table>
+</body>
+</html>
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
- <title>GPSBabel HTML Output</title>
- <style>
- p.gpsbabelwaypoint { font-size: 120%; font-weight: bold }
- </style>
-</head>
-<body>
-<p class="index">
-<a href="#GCGCA8">GCGCA8 - Oozy rat in a sanitary zoo</a><br>
-</p>
-
-<a name="GCGCA8"><hr></a>
-<table width="100%">
-<tr><td><p class="gpsbabelwaypoint">GCGCA8 - N35°55.300 W86°51.700 (16S 512480 3975269)<br>
-<a href="http://www.geocaching.com/seek/cache_details.aspx?guid=cda94cd6-d657-49bd-8e7e-0031ef1b2613">Oozy rat in a sanitary zoo</a> by robertlipe</p></td>
-<td align="right"><p class="gpsbabelcacheinfo">3 / 2<br>
-Unknown Cache / Unknown</p></td></tr>
-<tr><td colspan="2"><p class="gpsbabeldescshort">The cache is not at the coordinates above. These coords will get you to the correct park and within 1/2 mile of the cache. The cache is within 35 feet of the trail. It is not handicapped accessible. It is a nice walk in the woods that is practical for all ages. There is no space in the container for trading items. You should bring a writing stick and bug spray is recommended.</p>
-<p class="gpsbabeldesclong">So if the cache isn't at the above coordinates, where is it?
-
-<ul>
-
-<li>Too bad I hid a boot
-<li>Too hot to hoot
-<li>Never odd or even
-<li>Do geese see God?
-<li>"Do nine men interpret?" "Nine men," I nod
-<li>Rats live on no evil star
-<li>Go hang a salami, I'm a lasagna hog
-</ul>
-
-Now that it's intuitively obvious to even the most casual observer where the cache is, turn on your geo-mojo and go find it.
-<br>
-<img SRC="http://www.mtgc.org/mtgc_member-banner.gif" WIDTH="500" HEIGHT="40" ALT="Member of Middle Tennessee GeoCachers Club [www.mtgc.org]" BORDER="0"></a></p></p>
-<p class="gpsbabelhint"><strong>Hint:</strong> There Is No Hint</p>
-<p class="gpsbabellog">
-<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">littlepod</span> on <span class="gpsbabellogdate">2005-07-03</span><br>
-Enjoyed the puzzle. We seemed to be about 50ft off though. TFTC.</p>
-<p class="gpsbabellog">
-<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2005-04-29</span><br>
-TB Drop to show he's hanging out in Nashville until we blast off for Geowoodstock in a few weeks.</p>
-<p class="gpsbabellog">
-<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">Big Bumblebee</span> on <span class="gpsbabellogdate">2005-04-18</span><br>
-Found it a while ago. Thanks.</p>
-<p class="gpsbabellog">
-<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2005-03-27</span><br>
-I had to renew my permit with the CDC and in doing so, I trolled out here verified that the infectious ooze is fully within specification and industry accepted tolerance. Ooze On!</p>
-<p class="gpsbabellog">
-<span class="gpsbabellogtype">Found it</span> by <span class="gpsbabellogfinder">Virtual Babe</span> on <span class="gpsbabellogdate">2004-12-27</span><br>
-This was a great cache, however on this day I considered it a FIFM cache (Fun, Invigorating, Frustrating and Maddening), especially when the cache was not replaced in the proper spot by the previous cacher! Thanks anyway!!</p>
-<p class="gpsbabellog">
-<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2004-01-12</span><br>
-I got a complaint from the CDC about oozy rat this weekend. I went out tonight in the dark and verified that the infectious ooze is fully within specification and industry accepted tolerance. (Although I realize now I did misstate the cache container to the reporting officer when confronted. It's, uuuuh, smaller than I said.)</p>
-<p class="gpsbabellog">
-<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2003-10-04</span><br>
-In the expectation that this cache will get some traffic in the next 48 hours, Ryan and I checked it earlier today. The Rat is Oozing just as we planned it.</p>
-<p class="gpsbabellog">
-<span class="gpsbabellogtype">Write note</span> by <span class="gpsbabellogfinder">robertlipe</span> on <span class="gpsbabellogdate">2003-07-03</span><br>
-It won't earn him a smiley face, but I've confirmed that rickrich would have indeed sunk the battleship! Thanx for playing. You get a copy of the home game and some rice-a-roni...</p>
-</td></tr></table>
-</body></html>
\ No newline at end of file